#include "capplication.h"

#include "cappmanager.h"
#include "cimageicon.h"

#include <buola/widgets/cmenubar.h>
#include <buola/gui/x11/icccm.h>
#include <buola/gui/cicon.h>
#include <buola/gui/cmenu.h>
#include <buola/algorithm/container.h>

#define ID_KEEP_IN_DOCK             1
#define ID_NEW_WINDOW               2

#define ID_ACTIVATE_WINDOW_FIRST    100

namespace buola { namespace bdesktop {

CApplication::CApplication(CAppManager *pManager,os::CApplication *pType)
    :   mManager(pManager),
        mType(pType),
        mAppIcon(nullptr),
        mKeepInDock(false)
{
}

CApplication::~CApplication()
{
}

bool CApplication::ShouldHaveAppIcon()
{
    return mClients.size()||mKeepInDock;
}

void CApplication::AdjustAppIcon()
{
    if(mAppIcon)
    {
        if(!ShouldHaveAppIcon()) //remove it
        {
            mManager->GetDock()->RemoveIcon(mAppIcon);

            mAppIcon=nullptr;
        }
    }
    else if(!mAppIcon)
    {
        if(ShouldHaveAppIcon()) //place it
        {
            PImage lImage;
            
            if(mType)
            {
                lImage=gui::CIcon::Get(mType->GetIcon())->GetImage(128);
            }
        
            if(!lImage)
            {
                if(mClients.size())
                {
                    lImage=mClients[0]->mClient->GetTBIcon(CSize(128,128));
                }
                
                if(!lImage)
                {
                    lImage=gui::CIcon::Get("view-close")->GetImage(128);
                }
            }
    
            mAppIcon=new CImageIcon(lImage);
            mAppIcon->SetText(L"some app");
            mAppIcon->sClicked.Connect(&CApplication::OnAppIconClicked,this,_1);
            mAppIcon->sPosChanged.Connect(&CApplication::OnAppIconPosChanged,this,_1);
            mManager->GetDock()->AddIcon(mAppIcon,CDock::GROUP_APPS);
        }
    }
}

void CApplication::FillMenu(gui::PMenu pMenu)
{
    if(mClients.size())
    {
        for(int i=0;i<mClients.size();i++)
        {
            pMenu->Add(gui::new_menu_item(mClients[i]->mClient->mName));
        }
        
        pMenu->AddSeparator();
    }
    
    pMenu->Add(gui::new_menu_item(L"new window"))->eTriggered.Connect(&CApplication::OnNewWindow,this);

    if(mKeepInDock)
    {
        pMenu->Add(gui::new_menu_item(L"don't keep in dock"))->eTriggered.Connect(&CApplication::OnKeepInDock,this);
    }
    else
    {
        pMenu->Add(gui::new_menu_item(L"keep in dock"))->eTriggered.Connect(&CApplication::OnKeepInDock,this);
    }
}

void CApplication::OnClientAdded(CClient *pC)
{
    if(pC->ShouldBeInTaskBar())
    {
        SClient *lClient=new SClient;
        lClient->mClient=pC;
        lClient->mIcon=nullptr;
        mClients.push_back(lClient);
        pC->sRemoved.Connect(&CApplication::OnClientRemoved,this,lClient);

        AdjustAppIcon();

/*
        lClient->mIcon=new CThumbnailIcon;
        lClient->mIcon->SetText(pC->mName);
        lClient->mIcon->sClicked.Connect(&CApplication::OnIconClicked,this,_1,lClient);
        lClient->mIcon->sPosChanged.Connect(&CApplication::OnIconPosChanged,this,_1,lClient);
        mManager->GetDock()->InsertIcon(lClient->mIcon,CDock::GROUP_APPS,mAppIcon);
*/
    }
}

void CApplication::OnClientRemoved(SClient *pClient)
{
    if(pClient->mIcon)
        mManager->GetDock()->RemoveIcon(pClient->mIcon);
    erase_first_equal(mClients,pClient);
    
    AdjustAppIcon();
}

void CApplication::OnIconClicked(gui::CMouseEvent *pE,SClient *pClient)
{
    if(pE->mButton==gui::MOUSE_LEFT)
    {
        pClient->mClient->WMActivate();
    }
}

void CApplication::OnIconPosChanged(const CRect &pRect,SClient *pClient)
{
    gui::x11::icccm::write_net_wm_icon_geometry(pClient->mClient->GetID(),CIntRect(pRect+mManager->GetDock()->GetRootPos()));
}

void CApplication::OnAppIconClicked(gui::CMouseEvent *pE)
{
    if(pE->mButton==gui::MOUSE_LEFT)
    {
        if(mClients.size())
        {
            mClients[0]->mClient->WMActivate();
        }
        else if(mType)
        {
            mType->Run();
        }
    }
    else if(pE->mButton==gui::MOUSE_RIGHT)
    {
        gui::PMenu lMenu=new gui::CMenu;
        
        FillMenu(lMenu);

        mManager->GetDock()->ShowMenu(lMenu,pE->mRootPoint);
    }
}

void CApplication::OnAppIconPosChanged(const CRect &pRect)
{
}

void CApplication::OnKeepInDock()
{
    mKeepInDock=!mKeepInDock;

    AdjustAppIcon();
}


void CApplication::OnNewWindow()
{
    if(mType)
        mType->Run();
}

/*namespace bdesktop*/ } /*namespace buola*/ }
